#include "beaverthread.h"


#include <QSslSocket>

#include <QDebug>

#include "core.h"
#include "connector.h"
#include <QStringList>

class BeaverThread::BeaverThreadPrivate{
public:
	QSslSocket *socket;
};


//end of d-class
//------------------------------------------------------------------------------
BeaverThread::BeaverThread(QObject *parent) :
	QThread(parent),
	d(new BeaverThreadPrivate())
{
	d->socket = new QSslSocket();

	d->socket->moveToThread( this );
	moveToThread( this );


	connect( d->socket, SIGNAL(destroyed()), this, SLOT(quit()) );

	connect( d->socket, SIGNAL(disconnected()), this, SIGNAL(disconnected()) );


	connect( d->socket, SIGNAL(error(QAbstractSocket::SocketError)),
			 this, SLOT(slot_error(QAbstractSocket::SocketError)) );


	connect( d->socket, SIGNAL(connected()), this, SIGNAL(connected()) );

	connect( d->socket, SIGNAL(encrypted()), this, SIGNAL(encrypted()) );

	bool ignoreErrors = Core::instance()->settings()->value(
			Setting::sslErrorsIgnoreKey, Setting::sslErrorsIgnoreDef ).toBool();

	if( ignoreErrors ){
		connect( d->socket, SIGNAL(sslErrors(const QList<QSslError> &)),
				 d->socket, SLOT(ignoreSslErrors()));
	}else{
		connect( d->socket, SIGNAL(sslErrors(const QList<QSslError> &) ),
				 this, SLOT(slot_sslErrors(const QList<QSslError> &)) );
	}

	start();
}

BeaverThread::~BeaverThread(){
	qDebug() << Q_FUNC_INFO;
	delete d;
}

void BeaverThread::stop(){
	d->socket->disconnectFromHost();
	d->socket->deleteLater();

	qDebug() << Q_FUNC_INFO;

}

void BeaverThread::send(const QByteArray &data){
	d->socket->write( data );
}

void BeaverThread::slot_error(QAbstractSocket::SocketError error){
	qDebug() << "BeaverThread::slot_error(" << error << ")";
	qDebug() << d->socket->errorString();

	if( QAbstractSocket::HostNotFoundError == error ){
		emit hostNotFound();
		return;
	}

	if( QAbstractSocket::ConnectionRefusedError == error ){
		emit connectionRefused();
		return;
	}
}

void BeaverThread::slot_sslErrors(const QList<QSslError> &errors){
	qDebug() << "BeaverThread::slot_sslErrors" << errors.count() << errors;
	QStringList errorsList;
	for( int i = 0; i < errors.count(); i++ ){
		errorsList << errors.at(i).errorString();
		qDebug()<< i <<":"<< errors.at(i).error() << errors.at(i).errorString()
		<< errors.at(i).certificate().isValid();
	}

	emit sslError(errorsList);
}

void BeaverThread::connectToHostEncrypted(const QString &hostName,
										   quint16 port)
{
	qDebug() << this << thread() << currentThread();

	d->socket->connectToHostEncrypted( hostName, port );
}

bool BeaverThread::isConnected() const {
	if( d->socket )
		return (d->socket->state() == QAbstractSocket::ConnectedState);

	return false;
}

bool BeaverThread::isEncrypted() const {
	if( d->socket )
		return d->socket->isEncrypted();

	return false;
}

void BeaverThread::disconnectFromHost(){
	if( d->socket )
		d->socket->disconnectFromHost();
}
